package com.rtx.api.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.rtx.api.exception.RtxJsonValueException;

public class FastJsonUtils {
	
	public static int id = 0;
	
	public synchronized static List<Map<String,String>> getFormatJSON(String jsonStr) {
		id = 0;
		List<Map<String,String>> list = new ArrayList<Map<String,String>>();
		cycjson(jsonStr,"root",-1,list);
		return list;
	}

	private static void cycjson(String value,String parent,int parentid,List<Map<String,String>> list) {
		int type = isdeep(value);
		if(1==type) {
			JSONObject obj = JSON.parseObject(value);
			Map<String,String> structure = createStructure(id,parentid,parent,"object",null);
			list.add(structure);
			
			parentid = id;
			
			id++;
			
			//1 作为对象继续遍历
			for(String key:obj.keySet()) {
				cycjson(obj.getString(key),parent+"."+key,parentid,list);
			}
		}else if(2==type) {
			Map<String,String> structure = createStructure(id,parentid,parent,"array",null);
			list.add(structure);
			
			parentid = id;
			
			id++;
			
			
			List<String> array = JSON.parseArray(value,String.class);
			for(int i=0;i<array.size();i++) {
				cycjson(array.get(i),parent+"数组",parentid,list);
			}
		}else {
			Map<String,String> structure = createStructure(id,parentid,parent,"",value);
			list.add(structure);
			id++;
			return;
		}

	}
	
	private static Map<String,String> createStructure(int id,int parentid,String parent,String type,String value) {
		Map<String,String> structure = new HashMap<String, String>();
//		structure.put("id", id+"");
		structure.put("targetFieldCode", id+"");
		structure.put("targetParentField", parentid+"");
		String[] parentarray = parent.split("\\.");
		structure.put("fieldFullPath", parent);
		if(parentarray.length > 1) {
			structure.put("targetFieldName", parentarray[parentarray.length-1]);
		}else {
			structure.put("targetFieldName", parent);
		}
		structure.put("targetFieldType", type);
		structure.put("valueName", value);
		return structure;
	}

	/**
	 * 	是否继续遍历
	 *  1 作为对象继续遍历
	 *  2作为数据继续遍历
	 *  0不继续遍历 
	 * @param data
	 */
	private static int isdeep(String data) {
		int type = 0;
		boolean objCheck = data.startsWith("{")&&data.endsWith("}");
		boolean arrayCheck = data.startsWith("[")&&data.endsWith("]");
		if(objCheck) {
			type = 1;
		}else if(arrayCheck){
			type = 2;
		}else {
			type = 0;
		}
		return type;
	}
	
	
    public static void jsonFormat(Object jsonObject){
        String jsonFormatString = JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        System.out.println(jsonFormatString);
    }
    
	public static String queryByParentNode(String jsonValue,String queryNode) {
		String queryValue = null;
		try {
			queryByParentNode(jsonValue,"root",queryNode);
		}catch (RtxJsonValueException e) {
			queryValue = e.getMessage();
		}catch (Exception e) {
			throw e;
		}
		return queryValue;
	}
	
	private static void queryByParentNode(String value,String parent,String queryNode) {
		int type = isdeep(value);
		
		if(1==type) {
			if(parent.equals(queryNode)) {
				throw new RtxJsonValueException(value);
			}
			JSONObject obj = JSON.parseObject(value);
			for(String key:obj.keySet()) {
				String nextParent = parent+"."+key;
				queryByParentNode(obj.getString(key),nextParent,queryNode);
			}
		}else if(2==type) {
			if(parent.equals(queryNode)) {
				throw new RtxJsonValueException(value);
			}
			List<String> array = JSON.parseArray(value,String.class);
			for(int i=0;i<array.size();i++) {
				queryByParentNode(array.get(i),parent+"数组",queryNode);
			}
		}else {
			if(parent.equals(queryNode)) {
				throw new RtxJsonValueException(value);
			}
		}
	}
	
	
	/**
	 * 0为非JSON 格式字符串
	 * 1为jsonObject 对象
	 * 2为jsonArray 数组
	 * @param data
	 * @return
	 */
	public static int resolveJSONRootType(String data){
		int type = 0;
		boolean objCheck = data.startsWith("{")&&data.endsWith("}");
		boolean arrayCheck = data.startsWith("[")&&data.endsWith("]");
		if(objCheck) {
			type = 1;
		}else if(arrayCheck){
			type = 2;
		}else {
			type = 0;
		}
		return type;
	}

}
